gusucode.com > VC++视频目标检测演示帧间差分法-源码程序 > VC++视频目标检测演示帧间差分法-源码程序/code/Video Demo/StaticDetect.cpp
//Download by http://www.NewXing.com /******************************************************************* Motion target detection methods in video Author: jianglong date: 2006.06 Compiler: Microsoft Visual C++ 6.0 ********************************************************************/ #include "stdafx.h" //#include "Motiontrack.h" #include "StaticDetect.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CStatsticDetect::CStatsticDetect(int nwidth, int nheight) { m_nFrame = 0; count = 0; WIDTH = nwidth; HEIGHT = nheight; IMAGESIZE = WIDTH*HEIGHT; m_pCurImage = new BYTE[IMAGESIZE*3]; memset(m_pCurImage,0,IMAGESIZE*3); m_pGrayImage = new BYTE[IMAGESIZE]; memset(m_pGrayImage,0,IMAGESIZE); m_pBackground = new BYTE[IMAGESIZE]; memset(m_pBackground,0,IMAGESIZE); m_pBgImage = new BYTE[IMAGESIZE*3]; memset(m_pBgImage,0,IMAGESIZE*3); m_pDiffImage = new BYTE[IMAGESIZE]; memset(m_pDiffImage,0,IMAGESIZE); m_pDetectImage = new BYTE[IMAGESIZE*3]; memset(m_pDetectImage,0,IMAGESIZE*3); m_pBackHistgram = new short int[IMAGESIZE*256]; memset(m_pBackHistgram,0,IMAGESIZE*256*sizeof(short int)); m_pTemplate = new UINT[IMAGESIZE]; memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT)); m_pPreGrayImage = new BYTE[IMAGESIZE]; memset(m_pPreGrayImage,0,IMAGESIZE); image1 = new BYTE[IMAGESIZE]; memset(image1,0,IMAGESIZE); image2 = new BYTE[IMAGESIZE]; memset(image2,0,IMAGESIZE); image3 = new BYTE[IMAGESIZE]; memset(image3,0,IMAGESIZE); image4 = new BYTE[IMAGESIZE]; memset(image4,0,IMAGESIZE); } CStatsticDetect::~CStatsticDetect() { delete []m_pBackHistgram; delete []m_pDiffImage; delete []m_pBgImage; delete []m_pGrayImage; delete []m_pBackground; delete []m_pDetectImage; delete []m_pCurImage; delete []m_pTemplate; delete []image1; delete []image2; delete []image3; delete []image4; } void CStatsticDetect::ReceiveFrame(int index,BYTE* sBuf, DETECT_METHOD sMethod) { m_nFrame = index; memcpy(m_pCurImage,sBuf,WIDTH*HEIGHT*3); RGBToYUV(m_pCurImage,m_pGrayImage,WIDTH,HEIGHT); // if(index==1256) // SaveBmp(m_pGrayImage,WIDTH,HEIGHT,8,index); switch(sMethod) { case D_MULDIFFER: // ImageCopy(m_pGrayImage, m_nFrame); // if(m_nFrame>2) // { // MDiffImage(m_pDiffImage,WIDTH,HEIGHT,15); // DeNoise(m_pDiffImage,WIDTH,HEIGHT); //// SaveBmp(m_pDiffImage,WIDTH,HEIGHT,8,index); // } if(m_nFrame>0) { DiffImage(m_pGrayImage,m_pPreGrayImage,WIDTH,HEIGHT,20); DeNoise(m_pDiffImage,WIDTH,HEIGHT); } memcpy(m_pPreGrayImage,m_pGrayImage,IMAGESIZE); break; case D_MULMEAN: GetMultiData(m_pGrayImage,WIDTH,HEIGHT); if(m_nFrame>BACK_ALL_NUM) { if(m_nFrame==(BACK_ALL_NUM+1)) { GetBgImage(); memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT)); count = 0; SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index); } else if(m_nFrame%(2*BACK_ALL_NUM)==1) //更新背景图像 { GetBgImage(); memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT)); count = 0; SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index); } DiffImage(m_pGrayImage,m_pBackground,WIDTH,HEIGHT,THRESHOLD); DeNoise(m_pDiffImage,WIDTH,HEIGHT); } break; case D_STATISTIC: if(m_nFrame%BACK_SEQ_NUM==1) SetBgHistgram(m_pBackHistgram,m_pGrayImage,WIDTH,HEIGHT); if(m_nFrame>BACK_ALL_NUM) { if(m_nFrame==(BACK_ALL_NUM+1)) { GetBgByHistgram(m_pBackHistgram,m_pBackground,WIDTH,HEIGHT); memset(m_pBackHistgram,0,WIDTH*HEIGHT*256*sizeof(short int)); // SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index); } else if(m_nFrame%(3*BACK_ALL_NUM)==1) //更新背景图像 { GetBgByHistgram(m_pBackHistgram,m_pBackground,WIDTH,HEIGHT); memset(m_pBackHistgram,0,WIDTH*HEIGHT*256*sizeof(short int)); // SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index); } DiffImage(m_pGrayImage,m_pBackground,WIDTH,HEIGHT,THRESHOLD); DeNoise(m_pDiffImage,WIDTH,HEIGHT); if(index==1257) SaveBmp(m_pDiffImage,WIDTH,HEIGHT,8,index); } break; default: break; } } void CStatsticDetect::RGBToYUV(BYTE *sRGB,BYTE *sGray,int nWidth, int nHeight) { int i,j; for(j=0;j<nHeight;j++) { for(i=0;i<nWidth;i++) { sGray[nWidth*j+i]=(11*sRGB[3*(nWidth*j+i)]+59*sRGB[3*(nWidth*j+i)+1]+30*sRGB[3*(nWidth*j+i)+2])/100; } } } void CStatsticDetect::SetBgHistgram(short int *pHistgram, BYTE *sGray,int nWidth, int nHeight) { for(int j=0;j<nHeight;j++) { for(int i=0;i<nWidth;i++) { int p=*(sGray+j*nWidth+i)+256*(j*nWidth+i); *(pHistgram+p)=*(pHistgram+p)+1; } } } BOOL CStatsticDetect::GetBgByHistgram(short int *pHistgram,BYTE *sBg,int nWidth,int nHeight) { int j,i,k; for(j=0;j<nHeight;j++) { for(i=0;i<nWidth;i++) { int c=0; int color=0; for(k=0;k<256;k++) { if(*(pHistgram+256*(j*nWidth+i)+k)>c) { c=*(pHistgram+256*(j*nWidth+i)+k); color=k; } } *(sBg+j*nWidth+i)=color; } } for(j=0;j<nHeight;j++) { for( i=0;i<nWidth;i++) { memset(m_pBgImage+(nWidth*j+i)*3,*(sBg+j*nWidth+i),3); } } return TRUE; } void CStatsticDetect::DiffImage(BYTE *sGray,BYTE *pGray,int nWidth, int nHeight,int nThreshold) { int i,j; for(j=0;j<nHeight;j++) { for(i=0;i<nWidth;i++) { int diff=sGray[j*nWidth+i]-pGray[nWidth*j+i]; // m_pDiffImage[j*nWidth+i] = BYTE(abs(diff)); if(diff>nThreshold||diff<-nThreshold) { m_pDiffImage[j*nWidth+i]=255; } else { m_pDiffImage[j*nWidth+i]=0; } } } } void CStatsticDetect::DeNoise(BYTE *sGray,int nWidth, int nHeight) { int mode[3][3] = {-1,0,-1,-1,0,-1,-1,0,-1}; Erosion(sGray,nWidth,nHeight,mode); // Dilation(sGray,nWidth,nHeight,mode); Medianfilter_3x3(sGray,nWidth,nHeight); for(int j=0;j<nHeight;j++) { for(int i=0;i<nWidth;i++) { memset(m_pDetectImage+(nWidth*j+i)*3, *(m_pDiffImage+j*nWidth+i), 3); } } } void CStatsticDetect::Medianfilter_3x3(BYTE *sGray, int nWidth, int nHeight) { int i,j,k,l,count; int ii,mid; BYTE mean[9]; int ImageWidth, ImageHeight; ImageWidth = nWidth; ImageHeight = nHeight; BYTE* pBuf=new BYTE[ImageWidth*ImageHeight]; for(i=1;i<ImageHeight-1;i++) { for(j=1;j<ImageWidth-1;j++) { count = 0; for(k=-1;k<=1;k++) { for(l=-1;l<=1;l++) { mean[count]=sGray[(k+i)*ImageWidth+l+j]; count++; } } for(k=0;k<9;k++) { mid=mean[k]; ii=k; for(l=k+1;l<9;l++) { if(mid>mean[l]) { mid=mean[l]; ii=l; } } mean[ii]=mean[k]; mean[k]=mid; } pBuf[i*ImageWidth+j]= mean[4]; } } memcpy(sGray,pBuf,sizeof(BYTE)*ImageWidth*ImageHeight); delete []pBuf; } void CStatsticDetect::Dilation(BYTE *sGray,int nWidth, int nHeight,int structure[3][3]) { BYTE* t_gray = new BYTE[nWidth*nHeight]; BYTE pixel; int i,j,m,n; for(j=1;j<nHeight-1;j++) { for(i=1;i<nWidth-1;i++) { t_gray[j*nWidth+i] = (BYTE)0; for (m = 0;m < 3;m++ ) { for (n = 0;n < 3;n++) { if( structure[m][n] == -1) continue; pixel = sGray[(j+(m-2)+1)*nWidth + i + (n-1)]; if (pixel == 255 ) { t_gray[j*nWidth+i] = (BYTE)255; break; } } } } } memcpy(sGray,t_gray,nWidth*nHeight); delete []t_gray; } void CStatsticDetect::Erosion(BYTE *sGray,int nWidth, int nHeight,int structure[3][3]) { BYTE* t_gray = new BYTE[nWidth*nHeight]; BYTE pixel; int i,j,m,n; for(j=1;j<nHeight-1;j++) { for(i=1;i<nWidth-1;i++) { t_gray[j*nWidth+i] = (BYTE)255; for (m = 0;m < 3;m++ ) { for (n = 0;n < 3;n++) { if( structure[m][n] == -1) continue; pixel = sGray[(j+(m-2)+1)*nWidth + i + (n-1)]; if (pixel == 0 ) { t_gray[j*nWidth+i] = (BYTE)0; break; } } } } } memcpy(sGray,t_gray,nWidth*nHeight); delete []t_gray; } void CStatsticDetect::GetMultiData(BYTE *sGray,int nWidth, int nHeight) { count++; for(int j=0;j<nHeight;j++) for(int i=0;i<nWidth;i++) m_pTemplate[j*nWidth+i]+=sGray[j*nWidth+i]; } void CStatsticDetect::GetBgImage() { int i,j,t,pixel; for(j=0;j<HEIGHT;j++) { for(i=0;i<WIDTH;i++) { t = j*WIDTH+i; pixel = UINT(m_pTemplate[t]/count+0.5); if(pixel>255) m_pBackground[t] = BYTE(255); else if(pixel<0) m_pBackground[t] = BYTE(0); else m_pBackground[t] = BYTE(pixel); } } } void CStatsticDetect::SaveBmp(BYTE* buffer,int nwidth, int nheight, int bit, int index) { //write bmp BITMAPFILEHEADER bfh; bfh.bfType=0X4D42; bfh.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256 + nheight*nwidth); bfh.bfReserved1=0; bfh.bfReserved2=0; bfh.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256); BITMAPINFOHEADER bih; bih.biSize=sizeof(BITMAPINFOHEADER); bih.biWidth=nwidth; bih.biHeight=nheight; bih.biPlanes=1; bih.biBitCount=bit; bih.biCompression=BI_RGB; bih.biSizeImage=nheight*nwidth; bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; RGBQUAD palate[256]; for(int t=0;t<256;t++) { palate[t].rgbBlue=(BYTE)t; palate[t].rgbGreen=(BYTE)t; palate[t].rgbRed=(BYTE)t; palate[t].rgbReserved=0; } int bpl = (nwidth*8+31)/32*4; int imageSize = nheight*bpl; BYTE* imgData = NULL; if(bit == 8) { imgData = new BYTE[imageSize]; memcpy(imgData, buffer, imageSize); } if(bit == 24) { imgData = new BYTE[imageSize*3]; memcpy(imgData, buffer, imageSize*3); } CFile fp; CString path ; path.Format("Frame%03d.bmp",index); TRY { fp.Open("F:\\"+path,CFile::modeCreate | CFile::modeWrite); fp.Write((LPSTR)&bfh,sizeof(BITMAPFILEHEADER)); //写文件头 fp.Write((LPSTR)&bih,sizeof(BITMAPINFOHEADER)); //写信息头 if(bit==8) fp.Write((LPSTR)palate,sizeof(RGBQUAD)*256); //写调色板 fp.Write(imgData,nheight*nwidth);//写数据 } CATCH(CFileException,e) { THROW_LAST(); } END_CATCH delete []imgData; imgData = NULL; fp.Close(); } void CStatsticDetect::ImageCopy(BYTE *sGray, int m_num) { if(m_num==0) { memcpy(image1,sGray,IMAGESIZE); } else if(m_num==1) { memcpy(image2,sGray,IMAGESIZE); } else if(m_num==2) { memcpy(image3,sGray,IMAGESIZE); } else if(m_num==4) { memcpy(image4,sGray,IMAGESIZE); } else { memcpy(image1,image2,IMAGESIZE); memcpy(image2,image3,IMAGESIZE); memcpy(image3,image4,IMAGESIZE); memcpy(image4,sGray,IMAGESIZE); } } void CStatsticDetect::Subtract(BYTE *nImage, BYTE *nImage1, BYTE *nImage2, int nWidth, int nHeight, int nThresh) { int i,j; for(j=0;j<nHeight;j++) { for(i=0;i<nWidth;i++) { int t = j*nWidth+i; nImage[t] = nImage1[t]-nImage2[t]; if(abs(nImage[t])>nThresh) nImage[t] = 1; else nImage[t] = 0; } } } void CStatsticDetect::MDiffImage(BYTE *sGray,int nWidth, int nHeight, int nthresh) { BYTE *temp1 = new BYTE[nWidth*nHeight]; BYTE *temp2 = new BYTE[nWidth*nHeight]; Subtract(temp1, image1, image3, nWidth, nHeight, nthresh); Subtract(temp2, image2, image4, nWidth, nHeight, nthresh); int i,j; // for(j=0;j<nHeight;j++) // { // for(i=0;i<nWidth;i++) // { // int t=j*nWidth+i; // if(temp1[t]==1) // temp1[t] = 255; // else // temp1[t] = 0; // // if(temp2[t]==1) // temp2[t] = 255; // else // temp2[t] = 0; // // } // } // // DeNoise(temp1,WIDTH,HEIGHT); // SaveBmp(temp1,WIDTH,HEIGHT,8,7000); // DeNoise(temp2,WIDTH,HEIGHT); // SaveBmp(temp2,WIDTH,HEIGHT,8,7001); bool p; for(j=0;j<nHeight;j++) { for(i=0;i<nWidth;i++) { int t=j*nWidth+i; p = temp1[t] && temp2[t]; if(p) sGray[t] = 255; else sGray[t] = 0; } } delete []temp1; delete []temp2; }